﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Reflection;
using MovieRental.XmlDataService;
using MovieRental.XmlDataProviderCore.Exceptions;

namespace MovieRental.XmlDataProviderCore
{
    internal class XmlDataModel
    {
        private Dictionary<Type, XmlEntityInfo> _entityInfo = new Dictionary<Type, XmlEntityInfo>(new TypeEqualityComparer());

        internal bool ContainsType(Type entityType)
        {
            return _entityInfo.ContainsKey(entityType);
        }

        internal void AddEntity(object entity)
        {
            Type entityType = entity.GetType();
            AddEntity(entityType); 
        }

        internal void AddEntity(Type entityType)
        {
            if (ContainsType(entityType))
                return;
            XmlEntityAttribute entityAttribute = (XmlEntityAttribute)Attribute.GetCustomAttribute(entityType, typeof(XmlEntityAttribute));
            var idProperty = entityType.GetProperties().FirstOrDefault(x => Attribute.GetCustomAttribute(x, typeof(XmlPrimaryKeyAttribute)) != null);
            DataMemberAttribute idAttribute = (DataMemberAttribute)Attribute.GetCustomAttribute(idProperty, typeof(DataMemberAttribute));
            if (entityAttribute == null || idAttribute == null)
                throw new NotSupportedEntityException(entityType);
            if (idAttribute.Name == null)
                _entityInfo.Add(entityType, new XmlEntityInfo(entityAttribute.FileName, idProperty.Name));
            else
                _entityInfo.Add(entityType, new XmlEntityInfo(entityAttribute.FileName, idAttribute.Name));
        }

        internal XmlEntityInfo GetEntityInfo(object entity)
        {
            AddEntity(entity);
            return _entityInfo[entity.GetType()].Clone();
        }

        internal XmlEntityInfo GetEntityInfo(Type entityType)
        {
            AddEntity(entityType);
            return _entityInfo[entityType].Clone();
        }

    }
}
